package com.itxh.parser;

import com.itxh.model.BeanDefinition;
import com.itxh.model.PropertyValue;
import com.itxh.model.RuntimeBeanReference;
import com.itxh.model.TypedStringValue;
import com.itxh.registry.BeanDefinitionRegistry;
import com.itxh.utils.ReflectUtils;
import org.dom4j.Element;

import java.util.List;

/**
 * 该类就是具体来分发BeanDefinition由哪个BeanDefinitionParser来解析
 * 默认的Bean标签，就由该类来具体负责解析
 */
public class BeanDefinitionParserDelegate {
    private BeanDefinitionRegistry beanDefinitionRegistry ;


    public BeanDefinitionParserDelegate(BeanDefinitionRegistry beanDefinitionRegistry) {
        this.beanDefinitionRegistry = beanDefinitionRegistry;
    }

    /**
     *
     * @param beanElement <bean></bean>
     */
    public void parseDefaultBeanDefinition(Element beanElement) {
        String className = beanElement.attributeValue("class");
        if (className == null || className.equals("")){
            return ;
        }
        Class clazzType = ReflectUtils.resolveClassName(className);

        String beanName = beanElement.attributeValue("id");
        if (beanName == null || beanName.equals("")){
            beanName = beanElement.attributeValue("name");

            if (beanName == null || beanName.equals("")) {
                beanName = clazzType.getSimpleName();
            }
        }

        String scope = beanElement.attributeValue("scope");
        scope = scope == null || scope.equals("") ? "singleton" : scope;

        String initMethod = beanElement.attributeValue("init-method");

        BeanDefinition bd = new BeanDefinition(beanName,className);
        bd.setClazzType(clazzType);
        bd.setScope(scope);
        bd.setInitMethod(initMethod);

        List<Element> propertyList = beanElement.elements("property");
        for (Element propElement : propertyList) {
            // 解析property标签
            parsePropertyElement(propElement,bd);
        }

        // 注册BeanDefinition
        this.beanDefinitionRegistry.registerBeanDefinition(beanName,bd);
    }

    private void parsePropertyElement(Element propElement, BeanDefinition bd) {
        String name = propElement.attributeValue("name");
        String value = propElement.attributeValue("value");
        String ref = propElement.attributeValue("ref");

        if((value == null || value.equals("")) && (ref == null || ref.equals(""))){
            return ;
        }
        PropertyValue pv = null ;
        if(value != null && !value.equals("")){
            TypedStringValue typedStringValue = new TypedStringValue(value);

            Class targetType = ReflectUtils.resolveType(bd.getClazzType(),name);

            typedStringValue.setTargetType(targetType);

            pv = new PropertyValue(name,typedStringValue);
        }else if(ref != null && !ref.equals("")){
            RuntimeBeanReference beanReference = new RuntimeBeanReference(ref);
            pv = new PropertyValue(name,beanReference);
        }

        bd.addPropertyValue(pv);
    }


    // aop标签、mvc\context等标签中BeanDefinition的解析，走该方法
    public void parseCustomBeanDefinition(Element element) {

    }
}
